"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import math
import array
import re

def isMem(x):
  return re.match ("m([0-7])",x)

def getIndex(x):
  mo = re.match ("m([0-7])",x)
  return int(mo.group(1))

print "Welcome..."
print "" 

mem_index = 0
mem = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
index = 0
last = 0.0
res = 0.0
a = 0.0
b = 0.0
error = False
prev_msg = ""

while True:
  msg = raw_input("calcpylator:~$ ")

  if msg == ".":
    msg = prev_msg

  msg_tokens = msg.split()

  if len(msg_tokens) == 1:
    try:
      last = float(msg_tokens[0])
      res = str(last)
      print " >",res
    except ValueError:
      if msg_tokens[0] == "quit":
        break
      elif msg_tokens[0] == "clear":
        for register in range(len(mem)):
	  mem[register] = 0.0
	last = 0.0
	res = str(last)
	msg = ""
      elif msg_tokens[0] == "last":
        res = str(last)
	print " >",res
      elif msg_tokens[0] == "m":  
        mem[mem_index] = last
        res = "m"+str(mem_index)+" <- "+str(last)
        mem_index = (mem_index + 1) % 8
	print " >",res
      elif msg_tokens[0] == "p":
        for register in range(len(mem)):
	  print " > m"+str(register)+" = "+str(mem[register])
      elif msg_tokens[0] == "h":
        print " > Help menu: "
	print " > h -> shows this menu."
	print " > m -> stores last result on current memory register and increments pointer, up to 8 registers."
	print " >      When last register is reached, pointer goes back to first register"
	print " > p -> prints memory registers"
	print " > last -> prints last result. \"last\" also stores last result when evaluating."
	print " > m0..m7 -> these aliases store memory registers when evaluating."
	print " > a op b -> evaluates operation op which takes a anb b as inputs"
      elif msg_tokens[0] == "pi":
        last = math.pi
	res = str(last)
	print " >",res
      elif msg_tokens[0] == "e":
        last = math.e
	res = str(last)
	print " >",res
      else:
        res = "Not parsed: "+msg_tokens[0]
	print " >",res

  if len(msg_tokens) == 2:
    op = msg_tokens[0]
    a = float(msg_tokens[1])
    if op == "e":
      last = math.exp(a)
      res = str(last)
      print " >",res

  if len(msg_tokens) == 3:
    try:
      a = float(msg_tokens [0])
    except ValueError:
      if msg_tokens[0] == "last":
        a = last
      elif isMem(msg_tokens[0]):
        index = getIndex(msg_tokens[0])
        a = mem[index]
      elif msg_tokens[0] == "e":
        a = math.e
      elif msg_tokens[0] == "pi":
        a = math.pi
      else:
        print " > NaN"
	error = True
	last = 0

    op = msg_tokens[1]


    try:
      b = float(msg_tokens [2])
    except ValueError:
      if msg_tokens[2] == "last":
        b = last
      elif isMem(msg_tokens[2]):
        index = getIndex(msg_tokens[2])
        b = mem[index]
      elif msg_tokens[2] == "e":
        b = math.e
      elif msg_tokens[2] == "pi":
        b = math.pi
      else:
        print " > NaN"
	error = True
	last = 0

    if error == False:
      if op == "+":
        last = a + b
        res = str(last)
        print " >",res
      elif op == "-":
        last = a - b
        res = str(last)
        print " >",res
      elif op == "*":
        last = a * b
        res = str(last)
        print " >",res
      elif op == "/":
        last = a / b
        res = str(last)
        print " >",res
      elif op == "%":
        last = a % b
        res = str(last)
        print " >",res
      elif op == "=":
        if isMem (msg_tokens[0]):
          index = getIndex (msg_tokens[0])
          mem[index] = b
	  last = b
          res = "m"+str(index)+" <- "+str(b)
          print " >",res
      else:
        print "> NaN"
        res = 0
  error = False
  prev_msg = msg

print " > Bye!"
print ""
